package com.code.soulqlexpress.func;

import com.ql.util.express.Operator;
import com.ql.util.express.instruction.op.OperatorEqualsLessMore;

import java.lang.reflect.Array;
import java.util.List;

/**
 * @author songyang
 * @date 2022/4/21
 */
public class InOperator extends Operator {
    @Override
    public Object executeInner(Object[] list) throws Exception {
        Object obj = list[0];
        String msg;
        if (obj == null) {
            return Boolean.FALSE;
        } else if (!(obj instanceof Number) && !(obj instanceof String)) {
            msg = "对象类型不匹配，只有数字和字符串类型才才能执行 in 操作,当前数据类型是:";
            throw new Exception(msg + obj.getClass().getName());
        } else {
            int len;
            if (list.length != 2 || !list[1].getClass().isArray() && !(list[1] instanceof List)) {
                for (len = 1; len < list.length; ++len) {
                    boolean f = OperatorEqualsLessMore.executeInner("==", obj, list[len]);
                    if (f) {
                        return Boolean.TRUE;
                    }
                }

                return Boolean.FALSE;
            } else if (obj.equals(list[1])) {
                return true;
            } else {
                int i;
                boolean f;
                if (list[1].getClass().isArray()) {
                    len = Array.getLength(list[1]);

                    for (i = 0; i < len; ++i) {
                        f = OperatorEqualsLessMore.executeInner("==", obj, Array.get(list[1], i));
                        if (f) {
                            return Boolean.TRUE;
                        }
                    }
                } else if (list[1] instanceof List) {
                    List<Object> array = (List) list[1];

                    for (i = 0; i < array.size(); ++i) {
                        f = OperatorEqualsLessMore.executeInner("==", obj, array.get(i));
                        if (f) {
                            return Boolean.TRUE;
                        }
                    }
                }

                return false;
            }
        }
    }
}
